package com.qianniu.napi.common.util;

import com.qianniu.napi.common.config.Constants;
import okhttp3.HttpUrl;
import org.apache.cxf.jaxrs.client.WebClient;

import javax.ws.rs.core.Response;
import java.security.PrivateKey;
import java.security.Signature;
import java.util.Base64;
import java.util.UUID;

/**
 * HttpUrl工具类
 */
public class HttpUrlUtil {

    public static String SCHEMA = "WECHATPAY2-SHA256-RSA2048";
    public static String merchantId = "1592907601"; // 服务商

    public static String POST = "POST";
    public static String GET = "GET";
    //
    public static String host = "https://api.mch.weixin.qq.com";
    public static String APPLY_PATH = "/v3/applyment4sub/applyment/"; // 申请单url
    public static String CERT_PATH = "/v3/certificates"; // 获取微信平台证书url
    public static String APPLY_QUERY_PATH = "/v3/applyment4sub/applyment/applyment_id/"; // 查询申请状态

    /**
     * POST请求
     */
    public static String sendPost(String body) {
        String url = host + APPLY_PATH;
        try {
            // 获取微信平台商户证书序列号
            String wxSerialNo = CertUtil.getCertSerialNo();
            String authorization = getToken(POST, url, body);
            WebClient client = WebClient.create(host);
            client.reset();
            client.header("Content-Type", "application/json; charset=UTF-8");
            client.header("Accept", "application/json");
            client.header("user-agent", "application/json");
            client.header("Wechatpay-Serial", wxSerialNo);
            client.header("Authorization", authorization);
            client.path(APPLY_PATH);
            Response r = client.post(body);
            return r.readEntity(String.class);
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * get请求
     */
    public static String sendGet() {
        // 请求URL
        String url = host + CERT_PATH;
        try {
            String authorization = getToken(GET, url, "");
            WebClient client = WebClient.create(host);
            client.reset();
            client.header("Content-Type", "application/json; charset=UTF-8");
            client.header("Accept", "application/json");
            client.header("User-Agent", "application/json");
            client.header("Authorization", authorization);
            client.path(CERT_PATH);
            Response r = client.get();
            return r.readEntity(String.class);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * get请求
     */
    public static String sendGet(String applymentId) {
        // 请求URL
        String url = host + APPLY_QUERY_PATH + applymentId;
        try {
            String authorization = getToken(GET, url, "");
            WebClient client = WebClient.create(host);
            client.reset();
            client.header("Content-Type", "application/json; charset=UTF-8");
            client.header("Accept", "application/json");
            client.header("User-Agent", "application/json");
            client.header("Authorization", authorization);
            client.path(APPLY_QUERY_PATH + applymentId);
            Response r = client.get();
            return r.readEntity(String.class);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 获取加密串
     *
     * @param method
     * @param url
     * @param body
     * @return
     */
    public static String getToken(String method, String url, String body) {
        String nonceStr = String.valueOf(UUID.randomUUID());
        long timestamp = System.currentTimeMillis() / 1000;
        HttpUrl httpUrl = HttpUrl.parse(url);
        String message = buildMessage(method, httpUrl, timestamp, nonceStr, body);
        String signature = null;
        String certificateSerialNo = null;
        try {
            signature = sign(message.getBytes("utf-8"));
            certificateSerialNo = CertUtil.getSerialNo("");
        } catch (Exception e) {
            e.printStackTrace();
        }

        return SCHEMA + " mchid=\"" + merchantId + "\"," + "nonce_str=\"" + nonceStr + "\"," + "timestamp=\"" + timestamp + "\"," + "serial_no=\""
                + certificateSerialNo + "\"," + "signature=\"" + signature + "\"";
    }

    /**
     * 得到签名字符串
     */
    public static String sign(byte[] message) throws Exception {
        Signature sign = Signature.getInstance("SHA256withRSA");
        PrivateKey privateKey = CertUtil.getPrivateKey();
        sign.initSign(privateKey);
        sign.update(message);
        return Base64.getEncoder().encodeToString(sign.sign());
    }

    public static String buildMessage(String method, HttpUrl url, long timestamp, String nonceStr, String body) {
        String canonicalUrl = url.encodedPath();
        if (url.encodedQuery() != null) {
            canonicalUrl += "?" + url.encodedQuery();
        }
        return method + "\n" + canonicalUrl + "\n" + timestamp + "\n" + nonceStr + "\n" + body + "\n";
    }
}
